package cn.wolfcode.Controller;

import cn.wolfcode.qo.LogicException;
import cn.wolfcode.qo.jsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@ControllerAdvice
public class ExceptionController {

    /**
     *@ControllerAdvice : 控制器增强器
     *  其实就是在进入控制方法前，先进行一些增强的操作，底层也就是调用aop进行 处理
     *
     *  该类为异常处理类
     *  用于处理视图（跳转到errror页面），RequestBody（用于返回ajax请求的统一处理，逻辑异常），
     *
     *  自定义异常（自定义的异常信息）
     */


    /**
     *功能测试
     * 将employee的表名改为employee1，这时由于登录的返回是jsonResult，显示"系统异常，请联系管理员"
     * 正常登录后， 将employee的表名改为employee1，显示的是error错误页面，因为请求方法是返回String，视图类型
     */
    @ExceptionHandler(RuntimeException.class)  //表示处理捕抓什么异常，后执行下面的方法
    public String hadler(RuntimeException e, HandlerMethod handlerMethod, HttpServletResponse response){
        e.printStackTrace();//开发时找到bug
        //判断控制器返回的是视图还是jsonResult
        //如果返回的视图的话，就返回错误页面
        //如果返回的jsonResult的话，就想响应流写入jsonResult数据（因为方法的返回值是String，所以不能返回jsonResult类型）

        //handlerMedthod：拿到请求对应的执行方法
        //根据handlerMedthod拿到方法上面的注解
        //根据是否贴有的注解requestBody，判断放回的是视图String还是jsonResult类型
        if (handlerMethod.hasMethodAnnotation(ResponseBody.class) ) { //找到ResponseBody注解，说明请求的方法返回的是jsonResult类型
            response.setContentType("application/json;charset=UTF-8");
            try {
                    response.getWriter().print(JSON.toJSONString(new jsonResult(false,"系统异常，请联系管理员")));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return null;
        }

        //能执行到这里说明控制器的请求方法返回的是String，视图
        return "common/error";
    }

    /**
     * 上面的都是统一异常处理的处理，
     * 一个是由于公共错误（例如sql错误），显示 "系统异常，请联系管理员"
     * 一个是页面的返回错误，显示错误页面
     * 可是在开发中，我们需要自己 定义一些个性的异常信息
     * 例如：登录时，用户名不能为空，用户名或者密码不正确
     */
    @ExceptionHandler(LogicException.class)
    @ResponseBody
    public jsonResult LoficHadler(RuntimeException e, HandlerMethod handlerMethod, HttpServletResponse response){
        return new jsonResult(false,e.getMessage());
    }

}
